/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.ds;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.Statement;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import com.cqcis.uip.base.framework.utils.TimeUtil;

/**
 * 设置informix数据库锁等待时间
 * 
 * @author huangmy
 * @date 2008-3-3
 */
@Aspect
public class InformixDbLockModeWaitSetting {
	// private static Log log = LogFactory.getLog(InformixDbLockModeWaitSetting.class);

	private Map<Integer, String> callStacks = Collections.synchronizedMap(new HashMap<Integer, String>());
	private int monitor = 0;

	public int getMonitor() {
		return monitor;
	}

	public void setMonitor(int monitor) {
		if (monitor == 0) {
			this.callStacks.clear();
		}

		this.monitor = monitor;
	}

	@Around(value = "execution(* javax.sql.DataSource.getConnection(..))")
	public Object lockModeWait(ProceedingJoinPoint pjp) throws Throwable {
		Connection conn = (Connection) pjp.proceed();
		try {
			Statement stat = conn.createStatement();
			stat.executeUpdate("set isolation dirty read");
			stat.executeUpdate("set lock mode to wait 30");
			stat.close();
		} catch (Throwable t) {
			// ignore log.info("Catch Throwable in execute set lock mode.", t);
		}

		if (monitor > 0) {
			MonitorConnection mcon = new MonitorConnection(conn, callStacks);
			this.callStacks.put(conn.hashCode(), getString(new Throwable()));
			return mcon;
		} else {
			return conn;
		}
	}

	public Map<Integer, String> getCallStacks() {
		return this.callStacks;
	}

	public int getNumCallStacks() {
		return this.callStacks.size();
	}

	private String getString(Throwable th) {
		if (th == null)
			return "null";

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		PrintStream ps = new PrintStream(baos);
		th.printStackTrace(ps);
		String sReturn = baos.toString();
		try {
			baos.close();
		} catch (Exception ex) {
		}

		return TimeUtil.getCurrentTime() + "\n" + sReturn;
	}
}
